'use strict';

const BaseService = require('./base');
const path = require('path');
const _ = require('lodash');
const lowdb = require('lowdb');
const FileSync = require('lowdb/adapters/FileSync');
const storageKey = require('../const/storageKey');
const fs = require('fs');
const os = require('os');
const pkg = require('../../package.json');
const storageDb = 'db.json';
const { nanoid } = require("nanoid");
const idlength = 10;
const dayjs = require('dayjs');
const utils = require('../utils/utils');

class StorageService extends BaseService {
  /*
   * instance
   */
  instance(file = null) {
    if (!file) {
      const storageDir = this.getStorageDir();
      if (!fs.existsSync(storageDir)) {
        utils.mkdir(storageDir);
        utils.chmodPath(storageDir, '777');
      }
      file = path.normalize(storageDir + storageDb);
    }
    const isExist = fs.existsSync(file);
    if (!isExist) {
        return null;
    }
  
    const adapter = new FileSync(file);
    const db = lowdb(adapter);
  
    return db;
  }

  /*
   * getElectronIPCPort
   */
  getElectronIPCPort() {
    const key = storageKey.ELECTRON_IPC + '.port';
    const port = this.instance()
    .get(key)
    .value();
  
    return port;
  }

  /*
   * getStorageDir
   */
  getStorageDir() {
    const userHomeDir = os.userInfo().homedir;
    const storageDir = path.normalize(userHomeDir + '/' + pkg.name + '/');

    return storageDir;
  }

  /*
   * save config
   */
  async saveConfig(data) {
    const key = storageKey.SETTING_CONFIG;
    if (!this.instance().has(key).value()) {
      this.instance().set(key, []).write();
    }
    const item = this.instance().get(key).find({pid: data.pid}).value();
    if (_.isEmpty(item)) {
      this.instance()
      .get(key)
      .push(data)
      .write();
    } else {
      this.instance()
      .get(key)
      .find({pid: data.pid})
      .assign(data)
      .write();
    }

    return true;
  }

  /*
   * get config
   */
  async getConfig(pid) {
    const key = storageKey.SETTING_CONFIG;
    const data = this.instance()
    .get(key)
    .find({pid: pid})
    .value();

    return data;
  }

  /*
   * save upload file
   */
  async saveUploadFile(pid, data) {
    const history = storageKey.UPLOAD_HISTORY;
    const key = history + '.' + pid;
    if (!this.instance().has(history).value()) {
      this.instance().set(history, {}).write();
    }
    if (!this.instance().has(key).value()) {
      this.instance().set(key, []).write();
    }
    const now = dayjs();
    data.ctime = now.valueOf();
    data.ftime = now.format('YYYY-MM-DD HH:mm:ss');
    data.id = nanoid(idlength);
    this.instance()
    .get(key)
    .push(data)
    .write();

    return true;
  }

  /*
   * get file list
   */
  async getFileList(pid, page = 1, perPage = 10, content = '') {
    let offset = 0;
    let end = perPage;
    if (page > 1) {
      offset = (page - 1) * perPage;
      end = offset + perPage;
    }
    const key = storageKey.UPLOAD_HISTORY + "." + pid;
    const data = this.instance()
    .get(key)
    .filter(function(o) {
      let isHas = true;
      if (!_.isEmpty(content)) {
        const fileName = o.originalName;
        isHas = fileName.indexOf(content) !== -1 ? true : false;
      }
      return isHas;
    })
    .orderBy(['ctime'], ['desc'])
    .slice(offset, end)
    .value();

    return data;
  }

  /*
   * del file
   */
  async delFile(pid, fileId) {
    const key = storageKey.UPLOAD_HISTORY + "." + pid;
    const data = this.instance()
    .get(key)
    .remove({ id: fileId })
    .write();
    
    return data;
  }

  /*
   * get file count
   */
  async getFileCount(pid, content = '') {
    const key = storageKey.UPLOAD_HISTORY + "." + pid;
    const data = this.instance()
    .get(key)
    .filter(function(o) {
      let isHas = true;
      if (!_.isEmpty(content)) {
        const fileName = o.originalName;
        isHas = fileName.indexOf(content) !== -1 ? true : false;
      }
      return isHas;
    })
    .size()
    .value();

    return data;
  }

  /*
   * import data
   */
  async importData(data) {
    // config
    const configKey = storageKey.SETTING_CONFIG;
    const configData = _.get(data, [configKey], {});
    this.instance().set(configKey, configData).write();

    // upload history
    const historyKey = storageKey.UPLOAD_HISTORY;
    const historyData = _.get(data, [historyKey], {});
    this.instance().set(historyKey, historyData).write();

    return true;
  }
}

module.exports = StorageService;
